package ys.mihoyo.ymcc.service.impl;


import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import ys.mihoyo.ymcc.result.JSONResult;
import ys.mihoyo.ymcc.util.AssertUtil;
import ys.mihoyo.ymcc.util.BitStatesUtils;
import ys.mihoyo.ymcc.domain.Login;
import ys.mihoyo.ymcc.domain.User;
import ys.mihoyo.ymcc.domain.UserAccount;
import ys.mihoyo.ymcc.domain.UserBaseInfo;
import ys.mihoyo.ymcc.dto.RegParamDto;
import ys.mihoyo.ymcc.feign.UaaFeignClient;
import ys.mihoyo.ymcc.mapper.UserAccountMapper;
import ys.mihoyo.ymcc.mapper.UserBaseInfoMapper;
import ys.mihoyo.ymcc.mapper.UserMapper;
import ys.mihoyo.ymcc.service.IUserService;

import java.math.BigDecimal;


@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserBaseInfoMapper userBaseInfoMapper;
    @Autowired
    private UserAccountMapper userAccountMapper;
    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;
    @Autowired
    private UaaFeignClient uaaFeignClient;

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)//全局事务
    public void register(RegParamDto regParamDto) {
        //对数据进行校验【校验图形验证码和手机验证码是否正确】
        checkVerifyCode(regParamDto);

        //保存t_login里面的数据 为了得到注解id
        Long loginId = saveLoginin(regParamDto);

        //保存t_user---为了得到主键id
        User user = saveUser(regParamDto, loginId);
        //保存t_user_account
        saveUserAccount(user);
        //保存t_user_base_info
        saveUserInfo(user,regParamDto.getRegChannel());
    }

    private Long saveLoginin(RegParamDto regParamDto) {
        Login login = new Login();
        login.setPassword(regParamDto.getPassword());
        login.setUsername(regParamDto.getMobile());
        login.setType(login.LOG_WEB);
        //远程调用
        JSONResult jsonResult = uaaFeignClient.saveLogin(login);
       // Login data = (Login)jsonResult.getData();
       // Long loginId = data.getId();
        Long loginId = Long.valueOf(jsonResult.getData().toString());
        AssertUtil.isNotEquals(loginId,-1L ,"出错了" );
        return loginId;
    }

    /**
     * 赋值
     * @param user
     * @param regChannel
     */
    private void saveUserInfo(User user, Integer regChannel) {
        UserBaseInfo info = new UserBaseInfo();
        info.setId(user.getId());
        info.setCreateTime(System.currentTimeMillis());
        info.setGrowScore(0);
        info.setRegChannel(regChannel);
        info.setLevel(0);
        userBaseInfoMapper.insert(info);
    }

    /**
     * 赋值
     * @param user
     */
    private void saveUserAccount(User user) {
        UserAccount userAccount = new UserAccount();
        userAccount.setId(user.getId());
        userAccount.setCreateTime(System.currentTimeMillis());
        userAccount.setFrozenAmount(new BigDecimal("0"));
        userAccount.setUsableAmount(new BigDecimal("0"));
        userAccountMapper.insert(userAccount);
    }

    private User saveUser(RegParamDto regParamDto, Long loginId) {
        User u = new User();
        u.setCreateTime(System.currentTimeMillis());
        u.setLoginId(loginId);
        u.setPhone(regParamDto.getMobile());
        u.setNickName(regParamDto.getMobile());
        u.setSecLevel(0);
        //设置用户的状态 使用位运算
        long state = BitStatesUtils.addState(BitStatesUtils.OP_REGISTED, BitStatesUtils.OP_ACTIVED);
        state = BitStatesUtils.addState(state,BitStatesUtils.OP_AUTHED_PHONE);
        //以后有什么新的认证，使用原有的状态+新的状态
        u.setBitState(state);
        insert(u);
        return u;
    }

    /**
     * 数据校验
     * @param regParamDto
     */
    private void checkVerifyCode(RegParamDto regParamDto) {
        //获取数据
        //String imageCode = regParamDto.getImageCode();
        
        //校验图形码是否正确
        //Object o = redisTemplate.opsForValue().get(imageCode);
        //AssertUtil.isEqualsIgnoreCase(o.toString(),imageCode,"图形吗错误" );
        //手机验证码是否正确
        //redis:register:18244444441
        //"\"9832:1670255958050\"
        System.out.println("register:"+regParamDto.getMobile());
        String codeInRedis = redisTemplate.opsForValue().get("register:"+regParamDto.getMobile()).toString();
        System.out.println(codeInRedis);
        AssertUtil.isNotNull(codeInRedis,"手机验证码无效，请重新发送");
        //3.取出验证码进行比较
        String code = codeInRedis.split(":")[0];
        AssertUtil.isEqualsTrim(regParamDto.getSmsCode(),code,"验证码错误");
    }

    @Override
    public User queryByPhone(String phone) {
        Wrapper<User> wrapper=new EntityWrapper<>();
        //使用调用方法的形式，生成sql
        wrapper.eq("phone",phone); 
        return selectOne(wrapper);
    }
}
